//! gRPC通信层实现

pub mod service;
pub mod client;
pub mod server;

pub use service::*;
pub use client::*;
pub use server::*;

use tonic::transport::Server;
use std::sync::Arc;
use tokio::sync::RwLock;
use tracing::info;

/// gRPC配置
#[derive(Debug, Clone)]
pub struct GrpcConfig {
    /// 监听地址
    pub listen_addr: String,
    /// 最大并发连接数
    pub max_concurrent_streams: u32,
    /// 连接超时时间（毫秒）
    pub connect_timeout: u64,
    /// 请求超时时间（毫秒）
    pub request_timeout: u64,
    /// 是否启用压缩
    pub compression: bool,
}

impl Default for GrpcConfig {
    fn default() -> Self {
        Self {
            listen_addr: "[::]:9090".to_string(),
            max_concurrent_streams: 100,
            connect_timeout: 5000,
            request_timeout: 10000,
            compression: true,
        }
    }
}

/// gRPC服务管理器
pub struct GrpcService {
    /// 配置
    config: GrpcConfig,
    /// 服务实例
    server: Option<Server>,
    /// 客户端池
    clients: Arc<RwLock<HashMap<String, GrpcClient>>>,
}

impl GrpcService {
    pub fn new(config: GrpcConfig) -> Self {
        Self {
            config,
            server: None,
            clients: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    /// 启动gRPC服务
    pub async fn start(
        &mut self,
        cluster_service: Arc<dyn crate::grpc::service::ClusterService>,
        data_sync_service: Arc<dyn crate::grpc::service::DataSyncService>,
    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let addr = self.config.listen_addr.parse()?;
        
        let service = NacosGrpcService::new(cluster_service, data_sync_service);
        
        info!("Starting gRPC server on {}", addr);
        
        let server = Server::builder()
            .add_service(NacosServiceServer::new(service))
            .serve(addr);
            
        tokio::spawn(server);
        
        Ok(())
    }

    /// 获取客户端连接
    pub async fn get_client(&self,
        address: &str
    ) -> Result<GrpcClient, Box<dyn std::error::Error + Send + Sync>> {
        let mut clients = self.clients.write().await;
        
        if let Some(client) = clients.get(address) {
            return Ok(client.clone());
        }
        
        let client = GrpcClient::new(address.to_string()).await?;
        clients.insert(address.to_string(), client.clone());
        
        Ok(client)
    }

    /// 关闭所有连接
    pub async fn shutdown(&self
    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let mut clients = self.clients.write().await;
        clients.clear();
        Ok(())
    }
}

use std::collections::HashMap;
use crate::proto::nacos_service_server::NacosServiceServer;